var patchNoteRetries=0;

function getBool(obj, name)
{
    var b = getValue(obj, name);
    if((b != null) && (b != undefined))
    {
        if(b=='true') return true;
        if(b=='false') return false;
        return Boolean(b);
    }
    return false;
}

function getValue(values, varname)
{
    var v = getObject(values,varname);
    if(v == null) return null;
    if((v != null) && (v != undefined)
    &&((v.childNodes != null) && (v.childNodes != undefined))
    &&((v.childNodes[0] != null) && (v.childNodes[0] != undefined)))
    {
        return v.childNodes[0].nodeValue;
    }
    return null;
}

function getObject(values, varname)
{
	var v=null;
	for(var i=0;i<values.childNodes.length;i++)
	{
		if(values.childNodes[i].nodeName==varname)
		{
			v=values.childNodes[i];
			break;
		}
	}
    return v;
}

function isDigit(x)
{
    return ((x>='0')&&(x<='9'));
}

function GetSortIndexes(name)
{
    name=name.toLowerCase();
    var resp = new Object();
    resp.heNum=-1;
    resp.sbNum=-1;
    resp.isNumbered=false;
    resp.heNum=name.indexOf('he');
    if(resp.heNum < 0 
    || resp.heNum>=name.length-3 
    || !isDigit(name.charAt(resp.heNum+2)))
    {
        resp.heNum=-1;
        resp.sbNum=name.indexOf('sb');
        if(resp.sbNum<0 || resp.sbNum>=name.length-3 || !isDigit(name.charAt(resp.sbNum+2)))
            resp.sbNum=-1;
    }
    else
        resp.sbNum=-1;
    var x=resp.heNum;
    if(x<0) x=resp.sbNum;
    if(x<0) return resp;
    x++;
    resp.isNumbered=true;
    var finalNum=0;
    while(x<name.length && isDigit(name.charAt(++x)))
        finalNum=(finalNum*10)+Number(name.charAt(x));
    if(resp.heNum>=0)
        resp.heNum=finalNum;
    else
        resp.sbNum=finalNum;
    return resp;
}

function createEnvironment(values)
{
	if(getValue(values,'pver')=='3')
		return;
    var env=new Object();
    env.name=getValue(values,"name");
    env.displayName=getValue(values,"displayName");
    env.isOnline=getBool(values,"isOnline");
    env.patchOnly=getBool(values,"patchOnly");
    env.toolsOk=getBool(values,"toolsOk");
    env.allClientsOk=getBool(values,"allClientsOk");
    env.editcomments=getBool(values,"editcomments");
    env.sortIndexes=GetSortIndexes(env.displayName);
    
    // non-live environment data
    var shardObj=getObject(values,"shard");
    env.shardName = null;
    env.shardInetAddr = null;
    env.shardServer = null;
    env.shardInstance = null;
    env.shardPort = null;
    
    if((shardObj != null) && (shardObj != undefined))
    {
        env.shardName = getValue(shardObj,"name");
        env.shardInetAddr = getValue(shardObj,"inetAddr");
        if((env.shardInetAddr != null) && (env.shardInetAddr != undefined))
        {
            var x = env.shardInetAddr.indexOf(':');
            var y = env.shardInetAddr.lastIndexOf(':');
            if((x > 0) && (y > x))
            {
                env.shardServer = env.shardInetAddr.substr(0,x);
                env.shardPort = env.shardInetAddr.substr(x+1,y-x-1);
                env.shardInstance = env.shardInetAddr.substr(y+1);
            }
        }
        env.population = getValue(shardObj,"pop");
        env.shardBuildNum=getValue(shardObj,"buildNum");
        env.shardBranch=getValue(shardObj,"branch");
        env.shardBuildTimestamp=getValue(shardObj,"buildTimestamp");
        env.shardComment=getValue(shardObj,"comment");
    }
    if(!env.shardBuildNum)
    {
        env.shardBuildNum=getValue(values,"buildNum");
        env.shardBranch=getValue(values,"branch");
        env.shardBuildTimestamp=getValue(values,"buildTimestamp");
    }
    if(env.shardBuildTimestamp)
    {
        var x=env.shardBuildTimestamp.indexOf(':');
        if(x>0)
        {
            x=env.shardBuildTimestamp.indexOf(':',x+1);
            if(x>0)
                env.shardBuildTimestamp=env.shardBuildTimestamp.substr(0,x);
        }
    }
    env.isPublic=getBool(values,"isPublic");
    env.country=getValue(values,"country");
    env.language=getValue(values,"language");
    env.timezone=getValue(values,"timezone");
    env.comment=getValue(values,"comment");
    if((env.comment == null)||(env.comment == undefined)) 
        env.comment = (env.shardComment) ? env.shardComment : '';
    env.altShardHost=getValue(values,"altShardHost");
    env.altShardName=getValue(values,"altShardName");
    env.altShardBranch=getValue(values,"altShardBranch");
    env.altManifestUrl=getValue(values,"altManifestUrl");
    env.apesVer=getValue(values,"apesVer");
    env.codeVer=getValue(values,"codeVer");
    env.byfVer=getValue(values,"byfVer");
    env.dbVersion=getValue(values,"dbVersion");
    env.qbNum=getValue(values,"qbNum");
    env.buildTag = '';
    if(env.codeVer) env.buildTag+=', code: '+env.codeVer;
    if(env.apesVer) env.buildTag+=', apes: '+env.apesVar;
    if(env.byfVer) env.buildTag+=', byf: '+env.byfVer;
    if(env.dbVersion) env.buildTag+=', db: '+env.dbVersion;
    if(env.qbNum) env.buildTag+=', qb: '+env.qbNum;
    if((env.shardBuildNum) && (env.shardBranch) && (env.shardBuildTimestamp)) 
        env.buildTag+=', shard: '+env.shardBranch+' '+env.shardBuildNum+' '+env.shardBuildTimestamp;
    if(env.buildTag!='')
        env.buildTag=env.buildTag.substr(2);
    return env;        
}

function IsSortGreaterThan(a,b)
{
    var TRUE=1;
    var FALSE=-1;
    if(a.isOnline != b.isOnline)
    {
        if(!a.isOnline)
            return TRUE;
        return FALSE;
    }
    
    if(!b.sortIndexes.isNumbered)
    {
        if(a.sortIndexes.isNumbered)
            return TRUE;
        if( a.displayName.toLowerCase() > b.displayName.toLowerCase() )
            return TRUE;
        return FALSE;
    }
    if(!a.sortIndexes.isNumbered)
        return FALSE;
    if(b.sortIndexes.heNum >=0)
    {
        if(a.sortIndexes.sbNum >=0)
            return TRUE;
        return (a.sortIndexes.heNum > b.sortIndexes.heNum)?TRUE:FALSE;
    }
    if(a.sortIndexes.heNum >=0)
        return FALSE;
    return (a.sortIndexes.sbNum > b.sortIndexes.sbNum)?TRUE:FALSE;
}

function AjaxTestCall() 
{
    var req2 = init();
    req2.onreadystatechange = processRequest;
        
    function init() 
    {
        if (window.XMLHttpRequest)
            return new XMLHttpRequest();
        else 
        if (window.ActiveXObject)
            return new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    function processRequest() 
    {
        if (req2.readyState == 4) 
        {
            if (req2.status == 200) 
            {
                var values=req2.responseXML.getElementsByTagName("values")[0];
                var valueone=values.getElementsByTagName("valueone")[0].childNodes[0].nodeValue;
                var valuetwo=values.getElementsByTagName("valuetwo")[0].childNodes[0].nodeValue;
            }
            else
                log('ERROR',"AJAX Test Call: "+req2.status);
        }
    }

    this.execute = function() 
    {
        var url = platformurl+"test";
        var params = "valueone=" + encodeURIComponent("valueone") + "&" + "valuetwo=" + encodeURIComponent("?!&#\"valuetwo?!&#\"");
        req2.open("POST", url, true);
        req2.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        req2.setRequestHeader("Content-length", params.length);
        req2.setRequestHeader("Connection", "close");
        req2.send(params);
    }
}

function AjaxLogTransmissionCall() 
{
    var req = init();
    req.onreadystatechange = processRequest;
        
    function init() 
    {
        if (window.XMLHttpRequest)
            return new XMLHttpRequest();
        else 
        if (window.ActiveXObject)
            return new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    function processRequest() 
    {
        if (req.readyState == 4) 
        {
        	// dont really care
        }
    }

    this.execute = function() 
    {
        var memoryLogSize = Number(memoryLog.length);
        var memoryLogSizeStr = memoryLogSize.toString(16)
 	    while (memoryLogSizeStr.length < 8) 
 	    	memoryLogSizeStr = "0" + memoryLogSizeStr;
        var params="";
        params += "00000001\n";
        params += memoryLogSizeStr+"\n";
        params += "PATCHER.LOG\n";
        params += memoryLog;
        req.open("POST", bugcatcher_url, true);
        req.setRequestHeader("Content-Type", "application/text; charset=UTF-8");
        req.setRequestHeader("Content-length", params.length);
        req.setRequestHeader("Connection", "close");
        req.send(params);
    }
}

function AjaxGetPatchNotes() 
{
    var req = init();
    req.onreadystatechange = processRequest;
    var oldEnv = null;
    var self=this;
    var noPatchNotes = function(){
      $("#patchNotes").empty().append( $("#noPatchNotes").clone() );
    };
        
    function init() 
    {
        if (window.XMLHttpRequest)
            return new XMLHttpRequest();
        else 
        if (window.ActiveXObject)
            return new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    function processRequest() 
    {
        if (req.readyState == 4) 
        {
            if (req.status == 200) 
            {
            	patchNoteRetries=0;
                $("#patchNotes").scrollbar(false).insertHTML(req.responseText,"#contentPad",noPatchNotes);
                //TODO:** HEY SEAN -- WHY DOES THE LINE BELOW BREAK AUTO_ENVIRONMENT LOGINS??!?!?!?!?!?!
                if( $("#patchNotes").is(":visible") ){ $("#patchNotes").scrollbar(); }
            }
            else
            if(patchNoteRetries < 3)
            {
            	patchNoteRetries++;
            	self.execute(oldEnv);
            }
            else
            {
            	patchNoteRetries=0;
                noPatchNotes();
                log('ERROR',"Patch Notes Error status: "+req.status);
            }
        }
    }

    this.execute = function (env) {
        oldEnv = env;
        req.open("GET", patchNotesUrl[lang], true);

        var x = 10;
        //var x=user.patch_token.indexOf('_');
        if (x > 0) {
            var partOne = 10;
            var partTwo = 222222222222;
            req.setRequestHeader("Cookie", "md5=access=/*~expires=" + partOne + "~md5=" + partTwo + "; ");
            req.setRequestHeader("EAPatcher-gametoken", 10);
            req.setRequestHeader("EAPatcher-username", "ezmind1");
            req.setRequestHeader("EAPatcher-productid", "sztem_ezis");
            req.send('');
        }
    }
}

function AjaxAgreeToTermsCall() 
{
    var req = init();
    req.onreadystatechange = processRequest;
        
    function init() 
    {
        if (window.XMLHttpRequest)
            return new XMLHttpRequest();
        else 
        if (window.ActiveXObject)
            return new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    function processRequest() 
    {
        if (req.readyState == 4) 
        {
            if (req.status == 403) 
            {
                // yea!
            }
            else
                log('ERROR',"Agreement Error status: "+req.status);
        }
    }

    this.execute = function() 
    {
       var url = platformurl+"agree";
       var params = "id=" + 321 + "&" + "token=" + "HELLO" + "&" + "ver=" + 12;
       req.open("POST", url, true);
       req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
       req.setRequestHeader("Content-length", params.length);
       req.setRequestHeader("Connection", "close");
       req.send(params);
    }
}

function AjaxUpdateCommentCall() 
{
    var req = init();
    req.onreadystatechange = processRequest;
    var passBacks;
        
    function init() 
    {
        if (window.XMLHttpRequest)
            return new XMLHttpRequest();
        else 
        if (window.ActiveXObject)
            return new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    function processRequest() 
    {
        if (req.readyState == 4) 
        {
            if (req.status == 200) 
            {
                var response=req.responseXML.getElementsByTagName("result");
                var errormsg = '';
                if((response == null) ||(response == undefined) || (response[0]==null)|| (response[0]==undefined))
                    startEditShardComment(passBacks[0],passBacks[1],"Error updating comment, response was: unavailable\n");
                else
                {
                    response=response[0].childNodes[0].nodeValue;
                    if(response != 'true')
                        startEditShardComment(passBacks[0],passBacks[1],"Error updating comment, response was: "+response+"\n");
                    else
                    {/* kaplah! */ }
                }
            }
            else
                startEditShardComment(passBacks[0],passBacks[1],"Error updating comment, response was: "+req.status+"\n\n");
        }
    }

    this.execute = function(environment, token, comment, passBack)  
    {
       passBacks=passBack;
       var url = platformurl+"updatecomment";
       var params = "environment=" + encodeURIComponent(environment) + "&" + "shard=" + encodeURIComponent(environment) + "&" + "token=" + encodeURIComponent(token) + "&" + "comment=" + encodeURIComponent(comment);
       req.open("POST", url, true);
       req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
       req.setRequestHeader("Content-length", params.length);
       req.setRequestHeader("Connection", "close");
       req.send(params);
    }
}

function AjaxSingleLogin() 
{
    var req = init();
    req.onreadystatechange = processRequest;
    var emailAddress = '';
    var passwordCache = '';
    var tokenRequest = false;
        
    function init() 
    {
        if (window.XMLHttpRequest)
            return new XMLHttpRequest();
        else 
        if (window.ActiveXObject)
            return new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    function processRequest() 
    {
        if (req.readyState != 4)  // we're done
            return;
        disableLogins=false;
        enableButton();
        loginProgress.hide();
        $("body").removeClass('waiting');
        $("input[name=password]").val('');
            
        user = "";
        envs = [];
        loggedIn = true;
        showDevInfo = true;
        canEditComments = true;
        lastLogin= new Date();
				
        for(var key in req) {
           //log('INFO', '\nkey: ' + key + '\n' + 'value: ' + req[key] + '\n');
        }
				
        var req2 = req;
				
        if(req2.status != 403)
        {
            if(!tokenRequest)
            {
                error(strings[lang]["Sorry, this username and password combination is wrong."]).show();
                var forgot = $(".forgot");
                forgot.css({opacity:0});
                forgot[0].style.display="block";
                forgot.animate({opacity:1},200,'ease');
                log('INFO','Login failure recorded');
                setCaptchaHtml(req2);
            }
            else
            {
                $("#login").show();
            }
            return;
        }

        var response = req.responseXML.getElementsByTagName("response");
        log('INFO', 'RESPONSE: ' + response);
        if((response == null) || (response == undefined) || (response[0]==null) ||(response[0]==undefined))
        {
            error(strings[lang]["Server Not Responding"]).show();
            log('ERROR','Server did not respond to singlelogin');
            //return;
        }
        /*
        var userObj=response[0].getElementsByTagName("user")[0];
        user = new Object();
        user.token=userObj.getElementsByTagName("token")[0].childNodes[0].nodeValue;
        user.patch_token=userObj.getElementsByTagName("patch_token")[0].childNodes[0].nodeValue;
        user.persona=userObj.getElementsByTagName("persona")[0].childNodes[0].nodeValue;
        user.termsId=getValue(userObj,"terms_id");
        user.termsUrl=getValue(userObj,"terms_url");
        user.termsVer=getValue(userObj,"terms_ver");
        user.email=getValue(userObj,"email");
				*/
        loggedIn = true;
        lastLogin = new Date();
        
        // report machine specs, if necessary
        //ReportMachineSpecs();
        /*
        var environmentsObj=response[0].getElementsByTagName("environments");
        if((environmentsObj == null) || (environmentsObj == undefined) || (environmentsObj[0]==null) ||(environmentsObj[0]==undefined))
        {
            error(strings[lang]["GetEnvironments Failed"]).show();
            log('ERROR','GetEnvironments failed');
            //return;
        }
        /*
        environmentsObj=environmentsObj[0];
        for(var x=0;x<environmentsObj.attributes.length;x++)
            if(environmentsObj.attributes[x].nodeName == 'devinfo')
                showDevInfo = environmentsObj.attributes[x].nodeValue == 'true';
            else
            if(environmentsObj.attributes[x].nodeName == 'editcomments')
                canEditComments = environmentsObj.attributes[x].nodeValue == 'true';
        
        var envlist = environmentsObj.getElementsByTagName("environment");
        var x=0;
        for(var i=0;i<envlist.length;i++)
        {
            var envObj = envlist[i];
            var env = createEnvironment(envObj);
            if((env != null) && (env != undefined))
                envs[x++]=env;
        }
        envs = envs.sort(IsSortGreaterThan);
        buildEnvironments(envs);
				*/
        
        screen.login.hide();
        enableBackButton();
				/*
        if((user.termsUrl != null) 
        && (user.termsVer != null) 
        && (user.termsUrl != undefined) 
        && (user.termsVer != undefined) 
        && (user.termsUrl != '') 
        && (user.termsVer != ''))
        {
            var args = new Object();
            args.url = user.termsUrl;
            var loading = setTimeout(function(){ loading=false; $('#tos>.header>.loading').fadeIn(200); },200);
            var noTerms = function(){ $("#termsContent").empty().append( $("noTerms").clone() ); };
            // get the terms
            $.ajax(
              { url: user.termsUrl
              , type: "GET"
              , error: function(){ log('ERROR',"Unable to Establish Connection"); offline(); noTerms(); }
              , success: function(data) {
                  if(loading){ clearTimeout(loading); }
                  else{ $('#tos>.header>.loading').stop().fadeOut(200); }
                  $("#terms").insertHTML(data,"#termsContent",noTerms).scrollbar();
                } 
              }
             );
            disableButton();
            screen.tos.show();
        }
        else
        {*/
            //showEnvironmentsPageIfNecessary();
            disableButton();
            screen.tos.show();
        //}
        if(showDevInfo)
        	$("#language").show();
    }
    
    this.execute = function(email, password, captcha) 
    {
       emailAddress=email;
       passwordCache=password;
       tokenRequest = false;
       var url = platformurl+"singlelogin";
       var params = "email=" + encodeURIComponent(email);
       if((captcha != null)&&(captcha != undefined))
       {
           params += "&captchaSolution="+encodeURIComponent(captcha);
       }
       error.hide();
       req.open("POST", url, true);
       req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
       req.setRequestHeader("X-PASSWORD", password);
       req.setRequestHeader("Content-length", params.length);
       req.setRequestHeader("Connection", "close");
       req.send(params);
    }
    
    this.executeToken = function(token, patchToken) 
    {
       emailAddress = '';
       passwordCache=token;
       tokenRequest = true;
       var url = platformurl+"singletokenlogin";
       var params = "token=" + encodeURIComponent(token)+"&patch_token="+encodeURIComponent(patchToken);
       req2.open("POST", url, true);
       req2.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
       req2.setRequestHeader("Content-length", params.length);
       req2.setRequestHeader("Connection", "close");
       req2.send(params);
    }
}


function AjaxRefreshEnvironments() 
{
    var req2 = init();
    var callbackWhenComplete;
    var callbackWhenFail;
    req2.onreadystatechange = processRequest;
        
    function init() 
    {
        if (window.XMLHttpRequest)
            return new XMLHttpRequest();
        else 
        if (window.ActiveXObject)
            return new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    function processRequest() 
    {
        if (req2.readyState != 4)  // we're done
            return;
            
        //envs = [];
        if(req2.status != 200)
        {
            callbackWhenFail();
            return; // who cares...
        }
        
        var environmentsObj=req2.responseXML.getElementsByTagName("environments");
        if((environmentsObj == null) || (environmentsObj == undefined) || (environmentsObj[0]==null) || (environmentsObj[0]==undefined))
        {
            log('ERROR','RefreshEnvironments failed');
            callbackWhenFail();
            return; // not as important on a refresh
        }
        
        environmentsObj=environmentsObj[0];
        for(var x=0;x<environmentsObj.attributes.length;x++)
            if(environmentsObj.attributes[x].nodeName == 'devinfo')
                showDevInfo = environmentsObj.attributes[x].nodeValue;
            else
            if(environmentsObj.attributes[x].nodeName == 'editcomments')
                canEditComments = environmentsObj.attributes[x].nodeValue;
        
        var envlist = environmentsObj.getElementsByTagName("environment");
        var x=0;
        envs=[]; // the real restart
        var repickedEnv=null;
        for(var i=0;i<envlist.length;i++)
        {
            var envObj = envlist[i];
            var env = createEnvironment(envObj);
            if((env != null)&&(env != undefined))
            {
                envs[x++]=env;
                if((pickedEnv!=null) && (pickedEnv.name == env.name))
                    repickedEnv = env;
            }
        }
        envs = envs.sort(IsSortGreaterThan);
        callbackWhenComplete(repickedEnv);
    }
    
    this.execute = function(token, callback, failCallback) 
    {
       var url = platformurl+"environment";
       callbackWhenComplete=callback;
       callbackWhenFail=failCallback;
       var params = "token=" + encodeURIComponent(token);
       req2.open("POST", url, true);
       req2.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
       req2.setRequestHeader("Content-length", params.length);
       req2.setRequestHeader("Connection", "close");
       req2.send(params);
    }
}

function AjaxTest()
{
    // Ajax Test
    $.ajax(
      { url: internal_launchpad_url + 'test'
      , data: { valueone:'ping', valuetwo:'pong' }
      , dataType: 'xml'
      , type: "POST"
      , timeout: 5000
      , error: function()
        { 
            $.ajax(
              { url: external_launchpad_url + 'test'
              , data: { valueone:'ping', valuetwo:'pong' }
              , dataType: 'xml'
              , type: "POST"
              , timeout: 5000
              , error: function() { offline(); }
              , success: function(){ setExternalPlatform(); launcherReady(); }
              });
        }
      , success: function()
        {
    		if(SSN.Launcher.getSetting('LastMode', SSN.Launcher.getConfig('LastMode', ''))=='PROD')
    		{
                $.ajax(
                    { url: external_launchpad_url + 'test'
                    , data: { valueone:'ping', valuetwo:'pong' }
                    , dataType: 'xml'
                    , type: "POST"
                    , timeout: 5000
                    , error: function() { }
                    , success: function(){ $("body").removeClass("dev"); setExternalPlatform(); launcherReady(); }
                    });
    		}
    		else
    		{
	            setInternalPlatform();
	            launcherReady();
    		}
            $("body").addClass("internal");
        }
      });
}
